#include "dispatcheur_audio.h"
#include "commun/definitions.h"
#include "temps/retour_vers_le_futur.h"

namespace {
	struct tri_selon_temps {
		bool operator()(const evenement_audio &gauche, const evenement_audio &droite) const {
			return gauche.date() > droite.date();
		}
	};
}

dispatcheur_audio::dispatcheur_audio(type_temps latence_voulue) throw() : latence_voulue_(latence_voulue) {
	evenements_.reserve(instantane_du_piano::nombre_de_touches);
}

void dispatcheur_audio::deposer(instantane_du_piano &i) {
	// S'il y a une histoire de pédale qui change, on va le savoir tout de suite !
	if(i[pedale_douce] != instantane_courant_[pedale_douce])
		instantane_courant_[pedale_douce] = i[pedale_douce];
	
	// Itère sur toutes les touches pour constater des différences entre version locale et nouvel instantané déposé
	for(int t = do1; t < pedale_douce; ++t)
		if(i[t] && instantane_courant_[t] != i[t]) // une note s'allume, on crée un nouvel événement
			evenements_.push_back(evenement_audio(static_cast<touche_du_piano>(t), i.timestamp(), instantane_courant_[pedale_douce]));
	
	// Re-trie cette salade
	tri_selon_temps tr;
	if(!evenements_.empty())
	std::sort(evenements_.begin(), evenements_.end(), tr);
}
			  
lecture_son dispatcheur_audio::prochain_son_a_jouer() {
	evenement_audio &prochain_evt = evenements_.back();
	evenements_.pop_back();
	son &prochain_son = module_audio::instance().repertoire_des_notes[prochain_evt.note()];
	return lecture_son(prochain_son, prochain_evt.attenue());
}
